home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / debugtx.arc / 07FLOAT.DOC < prev    next >
Encoding:
Text File  |  1991-08-11  |  8.6 KB  |  199 lines

  1. CHAPTER 7    FLOATING POINT DEBUGGING                         7-1
  2.  
  3. If your machine has an 8087 or 80287 chip, D86 gives you 
  4. the best facilities for debugging code for the chip (which I 
  5. generically refer to as "the 87").
  6.  
  7. The display of the 87's state can be obtained by pressing the 
  8. Ctrl-F key.  If you don't have an 87 in your system, you won't 
  9. get the display.
  10.  
  11. You can also display floating-point numbers displayed in 86 
  12. memory, by using the FD, FQ, and FT specifiers described in 
  13. Chapter 6.
  14.  
  15. In the displays of floating point numbers, both on the 87 stack 
  16. and in 86 memory, I've taken great care to provide a display that 
  17. is both readable and accurate.  I rejected the algorithms for 
  18. display found in the popular reference books on the subject, 
  19. because they failed for several classes of extreme values. 
  20.  
  21.  
  22. The Floating-Point Display Window
  23.  
  24. The floating-point display you get with Ctrl-F contains the 
  25. following components: 
  26.  
  27. 1. The top 8 lines contain the contents of each floating-point 
  28.    register.  The registers are displayed as a stack, with ST(0) 
  29.    on top, numbered with "0:".  The format of the display depends 
  30.    on whether the number is a plain, normal number, or whether it 
  31.    is one of the exotic, non-normal types the 87 supports.  I'll 
  32.    briefly describe the exotic types at the end of this chapter.  
  33.    The possible displays are: 
  34.  
  35.    ----   (four hyphens), denoting a stack slot tagged empty.
  36.  
  37.    a decimal number, displayed in scientific notation if 
  38.         necessary.
  39.  
  40.    Infinity for an overflowed result.
  41.  
  42.    NaN for Not a Number, followed by the hexadecimal codes of
  43.         the significand field of the NaN
  44.  
  45.    Den for denormal, followed by the number of bits of precision 
  46.         lost, followed by the value of the number.
  47.         
  48.    Unn for unnormal, followed by the number of bits of precision 
  49.         lost, followed by the value of the number.
  50.         
  51.    Pseudo 0 for a pseudo zero, followed by the contents of the 
  52.         exponent field.
  53.                                                              7-2
  54.  
  55. 2. English-language displays for the infinity, precision, and 
  56.    rounding mode settings for the chip. 
  57.  
  58. 3. The value of the instruction pointer for the instruction that 
  59.    caused the last floating-point exception.  If all exceptions 
  60.    are masked this doesn't change. 
  61.  
  62. 4. The address of the memory operand for the instruction that 
  63.    caused the last floating-point exception.  If all exceptions 
  64.    are masked this doesn't change either.
  65.  
  66. 5. The value of the Tag register, for registers 7 through 0.  
  67.    These register numbers are NOT the same as the stack element 
  68.    numbers-- they are rotated by the value of ST, given on the 
  69.    next line.  The possible values for the Tag register fields 
  70.    are:
  71.  
  72.    f   for finite non-zero number
  73.    z   for zero
  74.    i   for infinite number
  75.    -   for empty slot
  76.  
  77. 6. The value of the stack pointer ST.  The tag-register number 
  78.    for ST(i) is ST plus i.
  79.  
  80. 7. A display of which 87 exceptions are masked; i.e., will not 
  81.    cause interrupts.  If the exception is masked, its letter is 
  82.    displayed.  If it is not masked (interrupt will occur), a 
  83.    blank is displayed.  The letters are:
  84.  
  85.    p  for precision exception
  86.    u  for underflow exception
  87.    o  for overflow exception
  88.    z  for zero-divide exception
  89.    d  for denormal exception
  90.    i  for invalid operation exception
  91.  
  92. 8. A display of which masked exceptions have occurred since the 
  93.    last time the status bits were cleared.  The exceptions have 
  94.    the same letters as the masked-display.
  95.  
  96. 9. A display of the 87 Condition Flags C3 through C0.  A 
  97.    displaying character is shown if the flag is set; a blank is 
  98.    shown if the flag is cleared.  The characters are:
  99.  
  100.    z  for C3  (corresponds to the Zero flag)
  101.    u  for C2  (set if a result is "unordered")
  102.    .  for C1
  103.    c  for C0  (corresponds to the Carry flag)
  104.  
  105. 10. Another display of C3 through C0, this time showing the 
  106.    results of an FXAM instruction.  This display is always 
  107.    present, even when FXAM is not the last flag-setting 
  108.    instruction executed (in which case the display is 
  109.    meaningless).
  110.                                                              7-3
  111. Exotic Flavors of Floating-Point Numbers
  112.  
  113. Some of the type of numbers possible in the floating-point 
  114. register display may seem a little strange to you if you haven't 
  115. had much experience with the 87.  It's a bit beyond the scope of 
  116. this manual to go into detail about them-- you should consult a 
  117. book such as "The 80286 Architecture" by Steve Morse for a 
  118. detailed discussion.  But here are brief descriptions to give you 
  119. a bit of an idea of what's going on: 
  120.  
  121. NaN (Not-a-Number) values are used to represent results that are
  122. totally different than any floating-point number that could be 
  123. provided.  A specific NaN (with hex value C000 0000 0000 0000) is 
  124. produced by the 87 whenever it can't cope with something, and the 
  125. Invalid Operation exception is masked.  Other NaN values might be
  126. loaded by a program from 86 memory, to be interpreted in any way 
  127. the program chooses.
  128.  
  129. For the rest of this discussion, let's introduce a little 
  130. terminology.  Floating point numbers use the a format that 
  131. follows the same principle as scientific notation.  In scientific 
  132. notation, one part of the number gives the significant digits of 
  133. the number, always "normalized" to fall between 1 and 10.  
  134. Another part of the number gives the magnitude of the number: the 
  135. power of ten that you multiply the first part by, to get the true 
  136. value.  For example, 2.34 * 10**2 is a normal, scientific 
  137. notation for 234.  (It can be written in A86 as 2.34E2).  2.34 * 
  138. 10**-2 is a normal scientific notation for 0.0234.  Note that 
  139. 0.234 * 10**-1 is a non-normal representation for the same 
  140. number: we have increased the size of the exponent from -2 to -1, 
  141. but the significant part is less than 1 instead of being between 
  142. 1 and 10. 
  143.  
  144. In the 87 formats, everything is binary, with bits instead of 
  145. digits.  There is a "significand" field, normalized whenever 
  146. possible so that the most significant bit is 1 (the value is 
  147. between 1 and 2).  There is the "exponent" field, giving the 
  148. (positive or negative) power of two that you multiply the 
  149. significand by, to get the true value. 
  150.  
  151. Denormals are produced when the result of an operation is non-
  152. zero, but is so tiny that its exponent is a negative number too 
  153. small to be represented in the 15-bit exponent field of an 87 
  154. register.  There is a trick called "gradual underflow" that makes 
  155. the best of the situation: the smallest possible exponent is 
  156. given, together with leading zeroes in the significand to signal 
  157. a further reduction in the exponent.  Each leading zero means 
  158. there is one less bit with which to represent the significand. 
  159.                                                              7-4
  160.  
  161. You can see denormals in action by typing Ctrl-F to get the 
  162. floating-point display, then typing the following commands to be 
  163. executed immediately: 
  164.  
  165.      FINIT
  166.      FLD 10.0
  167.      FLD 1.E-4931
  168.      FDIV 1
  169.  
  170. The result of the division is a denormal because 10 ** -4932 
  171. has a power-of-two exponent too small to be represented in 
  172. the 15-bit exponent field of the 87 register.  The display 
  173. indicates that 2 bits of precision have been lost-- two leading 
  174. zeroes have been forced into the significand field of the number.
  175.  
  176. Now press the F3 key to divide the number by another 10.  Now 5 
  177. bits of precision have been lost.  If you keep pressing the F3 
  178. key, you get more and more bits of precision lost.  The loss in 
  179. accuracy shows up in the number displayed.  Eventually, all bits 
  180. are lost, and the number collapses to zero.
  181.  
  182. What happens when we multiply a denormal number by 10, instead of 
  183. dividing it by 10?  The number becomes big enough to no longer 
  184. require the denormalization; but there's no way to recover the 
  185. bits of precision that have been lost.  To signal that bits have 
  186. been lost, the 87 retains the leading zeroes in the significand.  
  187. Numbers containing such zeroes without the minimum exponent are 
  188. called "unnormals". 
  189.  
  190. A certain kind of unnormal is a "pseudo-zero", obtained when all 
  191. the bits of precision are lost.  This can happen when you 
  192. multiply two unnormals.  The number of leading zero bits 
  193. (precision bits lost) of the answer is the sum of the bits lost 
  194. of the operands.  If the total is 64 bits or more, all precision 
  195. is lost-- the significand is zero.  But the exponent field is 
  196. nonzero, which brands the number as strange-- a true zero has 
  197. zeroes in the entire number, including the exponent field. 
  198.  
  199.